import {
  Injectable,
  ExecutionContext,
  CanActivate,
  ForbiddenException,
  HttpStatus,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { SKIP_LOGIN, SKIP_ACL } from '../decorator/public.decorator';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class AclAuthGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private configService: ConfigService,
  ) {}
  /*
        拿着method和path去request.user.permission中去比较，如果有就true，否则就是无权限
    */
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;

    const isPublic = this.reflector.getAllAndOverride<boolean>(SKIP_LOGIN, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) return true;
    const skipAuth = this.reflector.getAllAndOverride<boolean>(SKIP_ACL, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (skipAuth) return true;

    const request = context.switchToHttp().getRequest();
    const method = request.method.toLowerCase();
    const originalPath = request.path; // 保留完整路径，包含API前缀
    const pathWithoutPrefix = request.path.replace(
      `/${this.configService.get('API_PREFIX')}`,
      '',
    ); // 移除API前缀的路径
    const userPermissions = request.user?.permissions || [];

    // 检查用户是否有对应的路径和方法权限
    const hasPermission = userPermissions.some((permission: any) => {
      const methodMatch =
        permission.method === method || permission.method === '*';
      // 支持两种路径格式：带API前缀和不带API前缀
      const pathMatch =
        permission.url === originalPath || permission.url === pathWithoutPrefix;
      return methodMatch && pathMatch;
    });

    if (!hasPermission) {
      throw new ForbiddenException(
        `无权限执行 ${method.toUpperCase()} ${originalPath} 操作`,
      );
    }

    return true;
  }
}
